﻿namespace BM.Tools.WebControls.MForm.Controls.Modifiers
{
    using System;
    using System.Text;
    using System.Web.UI;

    using BM.Tools.WebControls.MForm.Controls.Helper;
    using BM.Tools.WebControls.MForm.Controls.Titles;

    /// <summary>
    /// An abstract modifier that changes the display of the control, to look like a table.    
    /// </summary>
    public abstract class TableDisplayModifier : OffspringsOwnerModifier
    {
        /// <summary>
        /// Gets or sets Title.
        /// </summary>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual TitleControl Title
        {
            get;
            set;
        }

        /// <summary>
        /// Gets the css class that can be added to the Title.
        /// </summary>
        protected abstract string TitleCssClass
        {
            get;
        }

        /// <summary>
        /// gets the title text
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <returns>
        /// the title text
        /// </returns>
        public virtual string GetTitleText(Offspring offspring)
        {
            return offspring.DisplayName;
        }

        /// <summary>
        /// returns a common string hash for all offspring item siblings
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <returns>
        /// the string hash.
        /// </returns>
        protected static string GetCommonSiblingsHash(Control offspring)
        {
            var builder = new StringBuilder(offspring.ClientID + "_");
            builder.Replace("-", string.Empty);
            builder.Replace(":", string.Empty);
            return builder.ToString();
        }

        /// <summary>
        /// Registers styles on the page so that items look like a table.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        protected abstract void AddStyles(OffspringsOwner offspring);

        /// <summary>
        /// Checks if the common title exists, if not, creates one.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        protected virtual void EnsureTitleCreated(OffspringsOwner offspring)
        {
            if (GetCommonTitle(offspring) == null)
            {
                CreateCommonTitle(offspring);
            }
        }

        /// <summary>
        /// Ensures that the common title is created on init to match viewstate
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected override void OnBasisInit(OffspringsOwner offspring, EventArgs e)
        {
            EnsureTitleCreated(offspring);
        }

        /// <summary>
        /// Ensures that the comon title still exists on pre render, becuase it could get lost during offspring recreation during databinding.
        /// Additionally adds styles to make items look like table elements.
        /// </summary>
        /// <param name="offspring">
        /// The offspring.
        /// </param>
        /// <param name="e">
        /// The event args.
        /// </param>
        protected override void OnBasisPreRender(OffspringsOwner offspring, EventArgs e)
        {
            EnsureTitleCreated(offspring);
            AddStyles(offspring);
        }

        private static TitleControl GetCommonTitle(OffspringsOwner offspring)
        {
            return offspring.Controls.FirstOfType<TitleControl>(false);
        }

        private void CreateCommonTitle(OffspringsOwner offspring)
        {
            TitleControl tc = Title ?? new TitleControl(GetTitleText(offspring));
            tc.CssClass += " " + TitleCssClass;
            offspring.Controls.AddAt(0, tc);
        }
    }
}